package controller;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Serializable;
import java.util.Collection;
import java.util.Date;
import java.util.List;

import javax.annotation.Resource;
import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.ejb.Timeout;
import javax.ejb.Timer;
import javax.ejb.TimerService;



import dtos.TechresourceDTO;
import dtos.TechticketDTO;
import utils.PrinterStatusBeanRemote;
import utils.TechresourceDAORemote;
import utils.TechticketDAORemote;
import utils.UserDAORemote;

/**
 * Session Bean implementation class PrinterTimerBean
 * 
 * @author Radulescu Cristina
 */
@Stateless
public class PrinterTimerBean implements PrinterTimerBeanRemote {

	/**
	 * Default constructor.
	 */
	public PrinterTimerBean() {
		// TODO Auto-generated constructor stub
	}

	@EJB
	TechresourceDAORemote c;
	@EJB
	PrinterStatusBeanRemote c1;
	@EJB
	TechresourceDAORemote c2;
	@EJB
	TechticketDAORemote c3;
	@EJB
	UserDAORemote c4;

	@Resource
	TimerService timerService;

	/**
	 * Method to start the timer
	 * 
	 * @param info
	 *            of type Serializable
	 */
	@Override
	public void startTimer(Serializable info) {
		timerService.createTimer(new Date(), 100000, info);
	}

	/**
	 * Method to stop the Timer
	 * 
	 * @param info
	 *            of type Serializable
	 */
	@Override
	public void stopTimer(Serializable info) {
		Timer timer = null;
		Collection<Timer> timers = timerService.getTimers();
		for (Object object : timers) {
			timer = ((Timer) object);
			if (timer.getInfo().equals(info)) {
				timer.cancel();
				break;
			}
		}
	}

	/**
	 * Method which checks if host is reachable using ping command
	 * 
	 * @param host
	 *            of type String
	 */
	public boolean isReachableByPing(String host) {
		try {
			String cmd = "";
			if (System.getProperty("os.name").startsWith("Windows")) {
				// For Windows
				cmd = "ping -n 1 " + host;
			} else {
				// For Linux and OSX
				cmd = "ping -c 1 " + host;
			}

			Process myProcess = Runtime.getRuntime().exec(cmd);
			myProcess.waitFor();

			if (myProcess.exitValue() == 0) {

				return true;
			} else {

				return false;
			}

		} catch (Exception e) {

			e.printStackTrace();
			return false;
		}
	}

	/**
	 * Method used to run a system command
	 * 
	 * @param command
	 *            : of type String
	 */
	public static void runSystemCommand(String command) {
		try {
			Process p = Runtime.getRuntime().exec(command);
			BufferedReader inputStream = new BufferedReader(
					new InputStreamReader(p.getInputStream()));
			String s = "";
			// reading output stream of the command
			while ((s = inputStream.readLine()) != null) {
				System.out.println(s);
			}
		}

		catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * Parameter used to count the number of times the timer has executed.
	 */
	private int count = 0;
	private int contor = 0;
	

	/**
	 * Method used to check the printer status, using a Timer. Inside the method
	 * all the printer ips are checked and if the printer status is not up to
	 * date, the printer values are updated
	 * 
	 * @param t
	 */
	@Override
	@Timeout
	public void checkPrinterStatus(Timer t) {
		System.out.println("salut");

//		count++;
		if (count >= 4) {
			t.cancel();
			return;
		}

		List<String> listIps = c.getAllPrinterIps();
		System.out.println(listIps.size());

		String prot = "http://";

		TechresourceDTO t1;
		for (String ip : listIps) {
			System.out.println(":::" + ip);
			t1 = c.getTechResourcesDTOByIp(ip).get(0);
			if (isReachableByPing(ip) == true) {

				String status;
				try {
					status = c1.calculateDeviceStats(prot + ip);
					if (!t1.getStatus().equals(status)) {

						System.out.println(status);
						System.out.println(isReachableByPing(ip));

						TechresourceDTO tr = c2.getTechResourcesDTOByIp(ip).get(0);
						tr.setStatus(status);
						c2.updateTechresource(tr);

					}
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}

				
			} else if (isReachableByPing(ip) == false) {
				contor++;
				TechresourceDTO tr = c2.getTechResourceDTOByIp(ip);
				tr.setStatus("Not Working");
				c2.updateTechresource(tr);
				TechticketDTO ticket = new TechticketDTO();
				ticket.setIdUser(c4.getAdmin().getId());
				ticket.setDate(new Date());
				ticket.setDescription("broken Printer/ping failed");
				ticket.setStatus("Pending");
				ticket.setIdTechresource(t1.getId());
				ticket.setProblemtype("broken printer");
				if(contor<2)c3.insertTechticket(ticket);
			}

		}

		listIps = c.getAllPrinterIps();

		for (String ip : listIps) {
			t1 = c.getTechResourceDTOByIp(ip);
			if (t1.getStatus().equals("broken") == true) {
				TechticketDTO ticket = new TechticketDTO();
				ticket.setIdUser(1);
				ticket.setDate(new Date());
				ticket.setDescription("broken Printer/ping failed");
				ticket.setStatus("Pending");
				ticket.setIdTechresource(t1.getId());
				ticket.setProblemtype("broken printer");
				c3.insertTechticket(ticket);
			}

		}

	}
}
